"""
通知日志数据模型
"""

from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, DECIMAL, Index
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship
from typing import List, Dict, Any, Optional
from datetime import datetime

from app.database import Base


class NotifyLog(Base):
    """通知日志表 - 简化版通知记录"""
    __tablename__ = "notify_logs"

    # 基础字段
    id = Column(Integer, primary_key=True, index=True, comment="通知日志ID")
    user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True, comment="用户ID")
    monitor_id = Column(Integer, ForeignKey("monitors.id"), nullable=False, index=True, comment="监控任务ID")
    
    # 通知结果字段
    success = Column(Boolean, nullable=False, default=False, comment="发送是否成功")
    channel = Column(String(20), nullable=False, default="EMAIL", comment="通知渠道：EMAIL/WECHAT/SMS")
    product_count = Column(Integer, nullable=False, default=0, comment="本次推送商品数量")
    
    # 商品信息字段（取第一个商品作为代表）
    product_name = Column(String(200), nullable=True, comment="商品名称")
    product_price = Column(DECIMAL(10, 2), nullable=True, comment="商品价格")
    product_image = Column(String(500), nullable=True, comment="商品图片URL")
    product_url = Column(String(500), nullable=True, comment="商品链接")
    
    # 时间和错误字段
    sent_at = Column(DateTime(timezone=True), server_default=func.now(), comment="发送时间")
    error_msg = Column(String(300), nullable=True, comment="错误信息（发送失败时）")
    
    # 关联关系
    user = relationship("User", back_populates="notify_logs")
    monitor = relationship("Monitor", back_populates="notify_logs")
    products = relationship("NotifyLogProduct", back_populates="notify_log", cascade="all, delete-orphan")
    
    # 性能优化索引
    __table_args__ = (
        Index('idx_notify_logs_user_time', 'user_id', 'sent_at'),
        Index('idx_notify_logs_monitor_time', 'monitor_id', 'sent_at'),
        Index('idx_notify_logs_success_time', 'success', 'sent_at'),
    )
    
    @classmethod
    def create_from_products(cls, 
                           user_id: int, 
                           monitor_id: int, 
                           products: List[Dict[str, Any]], 
                           success: bool, 
                           channel: str = "EMAIL", 
                           error_msg: Optional[str] = None,
                           monitor_type: str = "keyword") -> "NotifyLog":
        """
        从商品列表创建通知日志
        
        Args:
            user_id: 用户ID
            monitor_id: 监控任务ID
            products: 商品列表
            success: 发送是否成功
            channel: 通知渠道
            error_msg: 错误信息
            monitor_type: 监控类型（keyword/seller/shop）
            
        Returns:
            NotifyLog实例
        """
        # 取第一个商品作为代表显示
        first_product = products[0] if products else {}
        
        # 提取商品信息
        product_name = first_product.get('name', '')
        product_price = first_product.get('price')
        
        # 处理图片URL
        product_image = None
        if first_product.get('image_url'):
            product_image = first_product['image_url']
        elif 'thumbnails' in first_product and first_product['thumbnails']:
            # 兼容旧格式：thumbnails可能是字符串数组
            thumbnail = first_product['thumbnails'][0]
            if isinstance(thumbnail, str):
                product_image = thumbnail
            else:
                # 如果是对象格式，尝试获取url字段
                product_image = thumbnail.get('url') if hasattr(thumbnail, 'get') else str(thumbnail)
        
        # 构建商品链接 - 根据监控类型使用不同的URL格式
        product_url = None
        if first_product.get('id'):
            if monitor_type == "shop":
                # 店铺监控使用 shops/product 格式
                product_url = f"https://jp.mercari.com/shops/product/{first_product['id']}"
            else:
                # 关键词和卖家监控使用 item 格式
                product_url = f"https://jp.mercari.com/item/{first_product['id']}"
        
        return cls(
            user_id=user_id,
            monitor_id=monitor_id,
            success=success,
            channel=channel,
            product_count=len(products),
            product_name=product_name,
            product_price=product_price,
            product_image=product_image,
            product_url=product_url,
            error_msg=error_msg
        )
    
    @classmethod
    def create_failure_log(cls,
                          user_id: int,
                          monitor_id: int,
                          product_count: int,
                          error_msg: str,
                          channel: str = "EMAIL") -> "NotifyLog":
        """
        创建失败通知日志
        
        Args:
            user_id: 用户ID
            monitor_id: 监控任务ID
            product_count: 商品数量
            error_msg: 错误信息
            channel: 通知渠道
            
        Returns:
            NotifyLog实例
        """
        return cls(
            user_id=user_id,
            monitor_id=monitor_id,
            success=False,
            channel=channel,
            product_count=product_count,
            error_msg=error_msg[:300] if error_msg else None  # 限制错误信息长度
        )
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'id': self.id,
            'user_id': self.user_id,
            'monitor_id': self.monitor_id,
            'success': self.success,
            'channel': self.channel,
            'product_count': self.product_count,
            'product_name': self.product_name,
            'product_price': float(self.product_price) if self.product_price else None,
            'product_image': self.product_image,
            'product_url': self.product_url,
            'sent_at': self.sent_at.isoformat() if self.sent_at else None,
            'error_msg': self.error_msg
        }
    
    def __repr__(self) -> str:
        return (f"<NotifyLog(id={self.id}, user_id={self.user_id}, "
                f"monitor_id={self.monitor_id}, success={self.success}, "
                f"products={self.product_count})>")
